﻿using CartoLab.GeometryLib.Geometries;
using DbUtility;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using MAPSYMBOLLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;
using cartoGeometry = CartoLab.GeometryLib.Geometries;

namespace AEFunction.UI
{

    public partial class frmCreateTiles4MultiScale : Form
    {
        SortedList<double, string> scaleList = new SortedList<double, string>();
        Dictionary<string, double> scaleDic = new Dictionary<string, double>();
        AxMapControl mapControl = null;
        public frmCreateTiles4MultiScale(AxMapControl mp)
        {
            InitializeComponent();
            mapControl = mp;
        }


        class TileFeature
        {
            public string type;
            public Geometry shape;
            public string SymbolCode;
            public TileFeature(string t, string sc, Geometry g)
            {
                type = t;
                shape = g;
                SymbolCode = sc;
            }
        }

        struct NewCoordinate
        {
            public Coordinate c;
            public List<int> type;
        }


        private void btnOutput_Click(object sender, EventArgs e)
        {
            //XmlDocument docss = new XmlDocument();
            //docss.Load(@"E:\arcgisserver\arcgiscache\Output1028\Map10\conf.xml");
            //docss.NameTable;

            if (txtOutputPath.Text.Trim() == "")
            {
                MessageBox.Show("地图输出路径为空，选择输出位置！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtOutputPath.Focus();
                return;
            }
            //if (IsOutputPathContainChinese())
            //{
            //    MessageBox.Show("选择的路径中不能包含中文字符！");
            //    return;
            //}

            if (lsOutputScales.Items.Count == 0)
            {
                MessageBox.Show("请输入输出比例尺！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtNewScale.Focus();
                return;
            }

            //初始化目录
            string strOutputPath = txtOutputPath.Text.Trim();
            bool isInited = this.InitOutputPath(strOutputPath);

            if (!isInited)
            {
                MessageBox.Show("输出目录初始化失败！可能的原因\n   1. 输出目录不存在。\n   2. 输出目录不为空。", "输出错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            //初始化地图文档

            #region 获取切片宽度与高度
            int tileWidth = 0;
            if (!int.TryParse(txtTileWidth.Text.Trim(), out tileWidth))
            {
                MessageBox.Show("请输入正确的切片宽度！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtTileWidth.Focus();
                return;
            }
            int tileHeight = 0;
            if (!int.TryParse(txtTileHeight.Text.Trim(), out tileHeight))
            {
                MessageBox.Show("请输入正确的切片高度！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtTileHeight.Focus();
                return;
            }
            int mapScale = 0;
            if (!int.TryParse(txtMapScale.Text.Trim(), out mapScale))
            {
                MessageBox.Show("请输入正确的制图比例尺！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtTileHeight.Focus();
                return;
            }
            #endregion

            #region zhusi
            #region 切片
            double nowScale = mapControl.ActiveView.FocusMap.MapScale;
            IEnvelope fullExtent = new EnvelopeClass();
            fullExtent = mapControl.get_Layer(0).AreaOfInterest;
            for (int i = 1; i < mapControl.LayerCount; i++)
            {
                fullExtent.Union(mapControl.get_Layer(i).AreaOfInterest);
            }

            IPoint pStart = fullExtent.UpperLeft;
            double Width = fullExtent.Width;
            double Height = fullExtent.Height;

            ISymbolDB symbolDataBase = new SymbolDBClass();
            symbolDataBase.LoadFromXML(textBox1.Text);
            Dictionary<string, float> SymbolWidth = new Dictionary<string, float>();
            Dictionary<string, float> LineSymbolLength = new Dictionary<string, float>();
            //this.progressBar.Visible = true;
            int scalecount = 0;
            Dictionary<string, string> GBCodeToSymbolCode = new Dictionary<string, string>();
            foreach (var singlescale in scaleList)
            {
                scalecount++;
                this.progressBar.Value = 0;
                //this.progressText = "共有" + scaleList.Count + "个比例尺，当前在第" + scalecount.ToString()
                //    + "个";
                Directory.CreateDirectory(txtOutputPath.Text + "\\" + singlescale.Key.ToString());
                double scale = singlescale.Key;
                mapControl.ActiveView.FocusMap.MapScale = scale;
                //IPoint p = new ESRI.ArcGIS.Geometry.PointClass();
                //p.X = pStart.X + mapControl.ActiveView.Extent.Width / 2;
                //p.Y = pStart.Y - mapControl.ActiveView.Extent.Height / 2;
                //IEnvelope tmpE = mapControl.ActiveView.Extent;
                //tmpE.CenterAt(p);
                //mapControl.ActiveView.Extent = tmpE;
                //mapControl.Refresh();

                ESRI.ArcGIS.esriSystem.tagRECT rect = new ESRI.ArcGIS.esriSystem.tagRECT();
                rect.bottom = 256;
                rect.left = 0;
                rect.right = 256;
                rect.top = 0;
                int StartPX = 0;
                int StartPY = 0;
                mapControl.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(pStart, out StartPX, out StartPY);
                IEnvelope mapRect = new EnvelopeClass();
                mapControl.ActiveView.ScreenDisplay.DisplayTransformation.TransformRect(mapRect, ref rect, 1);
                double WorldTileWidth = mapRect.Height;
                int ScreenTileWidth = 256;
                double PixPerMeter = WorldTileWidth / ScreenTileWidth;
                #region 地图切片
                int nowCount = 0;
                int Hcount = (int)(Height / WorldTileWidth) + 1;
                int Wcount = (int)(Width / WorldTileWidth) + 1;
                AccessOperation ao = new AccessOperation(textBox2.Text);

                for (int i = 0; i < Hcount; i++)
                {
                    for (int j = 0; j < Wcount; j++)
                    {
                        nowCount++;
                            int per = (int)((float)nowCount * 100 / (float)Hcount / (float)Wcount);
                        this.progressBar.Value = per;
                        //backgroundWorker1.ReportProgress(per);
                        this.progressText.Text = ((float)nowCount * 100 / (float)Hcount / (float)Wcount).ToString() + "%";
                        #region 构建要素筛选范围
                        IPointCollection pc = new PolygonClass();
                        IPoint p1 = new PointClass();
                        IPoint p2 = new PointClass();
                        IPoint p3 = new PointClass();
                        IPoint p4 = new PointClass();
                        p1.X = pStart.X + j * WorldTileWidth - 0.1 * WorldTileWidth;
                        p1.Y = pStart.Y - i * WorldTileWidth + 0.1 * WorldTileWidth;
                        p2.X = pStart.X + (j + 1) * WorldTileWidth + 0.1 * WorldTileWidth;
                        p2.Y = pStart.Y - i * WorldTileWidth + 0.1 * WorldTileWidth;
                        p3.X = pStart.X + (j + 1) * WorldTileWidth - 0.1 * WorldTileWidth;
                        p3.Y = pStart.Y - (i + 1) * WorldTileWidth - 0.1 * WorldTileWidth;
                        p4.X = pStart.X + j * WorldTileWidth - 0.1 * WorldTileWidth;
                        p4.Y = pStart.Y - (i + 1) * WorldTileWidth - 0.1 * WorldTileWidth;

                        pc.AddPoint(p1);
                        pc.AddPoint(p2);
                        pc.AddPoint(p3);
                        pc.AddPoint(p4);
                        pc.AddPoint(p1);
                        IPolygon pPolygon = pc as IPolygon;
                        #endregion

                        #region 构建要素切片框

                        Coordinate[] coords = new Coordinate[5];
                        Coordinate leftUp = null;

                        Coordinate rightBottom = null;
                        leftUp = new Coordinate(pStart.X + j * WorldTileWidth, pStart.Y - i * WorldTileWidth);
                        rightBottom = new Coordinate(pStart.X + (j + 1) * WorldTileWidth, pStart.Y - (i + 1) * WorldTileWidth);
                        coords[0] = leftUp;
                        coords[1] = new Coordinate(rightBottom.X, leftUp.Y);
                        coords[2] = new Coordinate(rightBottom.X, rightBottom.Y);
                        coords[3] = new Coordinate(leftUp.X, rightBottom.Y);
                        coords[4] = leftUp;
                        LinearRing lr = new LinearRing(coords);
                        Geometry tileGeo = new CartoLab.GeometryLib.Geometries.Polygon(lr);
                        #endregion

                        ISpatialFilter pSpatialFilter = new SpatialFilterClass();
                        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                        pSpatialFilter.Geometry = pPolygon;
                        List<TileFeature> tileFeatures = new List<TileFeature>();
                        for (int k = 0; k < mapControl.LayerCount; k++)
                        {
                            IFeatureLayer pBackLayer = mapControl.get_Layer(k) as IFeatureLayer;
                            IFeatureSelection pFeatureSelection = pBackLayer as IFeatureSelection;
                            pFeatureSelection.Clear();

                            pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                            ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
                            int ddd = pFeatureSelection.SelectionSet.Count;
                            if (pFeatureSelection.SelectionSet.Count == 0)
                                continue;
                            IEnumIDs pEnumIDs = pSelectionSet.IDs;
                            int id = pEnumIDs.Next();
                            while (id != -1)
                            {
                                IFeature pFeature = pBackLayer.FeatureClass.GetFeature(id);

                                TileFeature f = EsirFeatureToTileFeature(pFeature, ao, GBCodeToSymbolCode);
                                if (f == null)
                                {
                                    id = pEnumIDs.Next();
                                    continue;
                                }

                                Geometry ExtGeo = null;
                                var ratio = singlescale.Key / 50000;
                                float width = 0;
                                if (SymbolWidth.Keys.Contains(f.SymbolCode))
                                    width = SymbolWidth[f.SymbolCode];
                                else
                                {
                                    width = GetSymbolWidth(symbolDataBase, f.SymbolCode, f.type);
                                    width *= (float)(scale / 50000);
                                    SymbolWidth.Add(f.SymbolCode, width);
                                }
                                ExtGeo = f.shape.Buffer(width);
                                bool isContains = tileGeo.Contains(ExtGeo);
                                bool isIntersects = tileGeo.Intersects(ExtGeo);
                                if (f.type == "Point")
                                {
                                    #region 点
                                    if (isContains || isIntersects)
                                        tileFeatures.Add(f);
                                    #endregion
                                }
                                else if (f.type == "Line")
                                {
                                    #region 线
                                    //若相交
                                    if (tileGeo.Intersects(f.shape))
                                    {
                                        //若完全包含
                                        if (tileGeo.Contains(f.shape))
                                        {
                                            tileFeatures.Add(f);
                                        }
                                        else//相交不包含，需要对线进行切割和延伸
                                        {
                                            LineString tmpLr = new LineString(coords);
                                            Geometry intersectGeo = tmpLr.Intersection(f.shape);
                                            //将对象根据符号单元长度分为N分
                                            float lineSymbolLine = 0;
                                            if (LineSymbolLength.ContainsKey(f.SymbolCode))
                                                lineSymbolLine = LineSymbolLength[f.SymbolCode];
                                            else
                                            {
                                                lineSymbolLine = GetLineSymbolLength(symbolDataBase, f.SymbolCode);
                                                lineSymbolLine *= (float)(scale / 50000);
                                                LineSymbolLength.Add(f.SymbolCode, lineSymbolLine);
                                            }
                                            if (lineSymbolLine == 0)
                                            {
                                                id = pEnumIDs.Next();
                                                continue;
                                            }
                                            LineString l = (LineString)f.shape;
                                            //等分点
                                            Coordinate[] divisionPts = GetLineDivisionPoints(l, lineSymbolLine);
                                            //筛选过会的交点
                                            List<Coordinate> intsersectPts = new List<Coordinate>();
                                            for (int n = 0; n < intersectGeo.Coordinates.Length; n++)
                                            {
                                                if (!divisionPts.Contains(intersectGeo.Coordinates[n]))
                                                    intsersectPts.Add(intersectGeo.Coordinates[n]);
                                            }

                                            #region 将交点和等分点按线的顺序构造成一个新的坐标
                                            List<NewCoordinate> newLine = new List<NewCoordinate>();
                                            //先将原点坐标插入序列
                                            foreach (var c in f.shape.Coordinates)
                                            {
                                                NewCoordinate nc = new NewCoordinate();
                                                nc.c = c;
                                                nc.type = new List<int>();
                                                nc.type.Add(1);
                                                newLine.Add(nc);
                                            }
                                            //再依次将交点和符号化节点插入
                                            foreach (var item in intsersectPts)
                                            {
                                                NewCoordinate nc = new NewCoordinate();
                                                nc.c = item;
                                                nc.type = new List<int>();
                                                nc.type.Add(2);
                                                newLine = InsertPointInLine(newLine, nc);
                                            }
                                            foreach (var item in divisionPts)
                                            {
                                                NewCoordinate nc = new NewCoordinate();
                                                nc.c = item;
                                                nc.type = new List<int>();
                                                nc.type.Add(3);
                                                newLine = InsertPointInLine(newLine, nc);
                                            }
                                            #endregion

                                            //将根据交点和符号化节点将对象分为若干个对象

                                            List<List<NewCoordinate>> allNewF = new List<List<NewCoordinate>>();
                                            List<NewCoordinate> newF = new List<NewCoordinate>();
                                            #region 根据交点将对象分为若干个对象
                                            for (int kk = 0; kk < newLine.Count; kk++)
                                            {
                                                if (kk == newLine.Count - 1)
                                                {
                                                    newF.Add(newLine[kk]);
                                                    List<NewCoordinate> newF1 = new List<NewCoordinate>();
                                                    foreach (var item in newF)
                                                    {
                                                        newF1.Add(item);
                                                    }
                                                    allNewF.Add(newF1);
                                                    newF.Clear();
                                                    break;
                                                }

                                                if (newF.Count == 0)
                                                {
                                                    newF.Add(newLine[kk]);
                                                    continue;
                                                }
                                                else
                                                {
                                                    newF.Add(newLine[kk]);
                                                    if (newLine[kk].type.Contains(2))
                                                    {

                                                        List<NewCoordinate> newF1 = new List<NewCoordinate>();
                                                        foreach (var item in newF)
                                                        {
                                                            newF1.Add(item);
                                                        }
                                                        allNewF.Add(newF1);
                                                        newF.Clear();
                                                        kk--;
                                                        continue;
                                                    }


                                                }
                                            }
                                            #endregion
                                            #region 将在瓦片外的线删掉
                                            for (int m = 0; m < allNewF.Count; m++)
                                            {
                                                newF = allNewF[m];
                                                foreach (var c in newF)
                                                {
                                                    if (tileGeo.Touches(new CartoLab.GeometryLib.Geometries.Point(c.c)) || tileGeo.Contains(new CartoLab.GeometryLib.Geometries.Point(c.c)))
                                                    {
                                                        ;
                                                    }
                                                    else
                                                    {
                                                        allNewF.RemoveAt(m);
                                                        m--;
                                                        break;
                                                    }
                                                }
                                            }
                                            #endregion

                                            foreach (var item in allNewF)
                                            {

                                                List<Coordinate> coors = new List<Coordinate>();
                                                #region 将线的两段向符号化节点延伸
                                                NewCoordinate first = item[0];
                                                NewCoordinate last = item[item.Count - 1];

                                                int firstIndex = newLine.IndexOf(first);
                                                for (int m = firstIndex - 1; m >= 0; m--)
                                                {
                                                    coors.Insert(0, newLine[m].c);
                                                    if (newLine[m].type.Contains(3))
                                                        break;
                                                }
                                                foreach (var geo in item)
                                                {
                                                    coors.Add(geo.c);
                                                }

                                                int lastIndex = newLine.IndexOf(last);
                                                for (int m = lastIndex + 1; m < newLine.Count; m++)
                                                {
                                                    coors.Add(newLine[m].c);
                                                    if (newLine[m].type.Contains(3))
                                                        break;
                                                }
                                                #endregion

                                                ClearSomeLinePoint(coors);
                                                Geometry newG = new LineString(coors.ToArray());
                                                TileFeature newFeature = new TileFeature(f.type, f.SymbolCode, newG);
                                                tileFeatures.Add(newFeature);
                                            }

                                        }

                                    }

                                    #endregion
                                }
                                else
                                {
                                    #region 面
                                    if (isContains || isIntersects)
                                    {
                                        if (f.shape.GetType().Name == "MultiPolygon")
                                        {
                                            for (int geoCount = 0; geoCount < f.shape.NumGeometries; geoCount++)
                                            {
                                                TileFeature ff = new TileFeature(f.type, f.SymbolCode, f.shape.GetGeometryN(geoCount));
                                                ExtGeo = ff.shape.Buffer(width);
                                                isContains = tileGeo.Contains(ExtGeo);
                                                isIntersects = tileGeo.Intersects(ExtGeo);
                                                if (isContains || isIntersects)
                                                {
                                                    tileFeatures.Add(ff);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            tileFeatures.Add(f);
                                        }

                                    }
                                    #endregion
                                }
                                id = pEnumIDs.Next();
                            }
                        }
                        TileInfo ti = new TileInfo();
                        ti.TileScale = scale;
                        ti.MapScale = mapScale;
                        ti.resolution = PixPerMeter;
                        ti.TileHeight = tileHeight;
                        ti.TileColumnCount = Wcount;
                        ti.TileRowCount = Hcount;
                        SaveTileToXml(tileFeatures.ToArray(), txtOutputPath.Text + "\\" + singlescale.Key.ToString() + "\\" + i.ToString() + "_" + j.ToString() + ".xml", tileGeo.Coordinates[3], ti);
                    }
                }
                #endregion
            }
            #endregion
            #endregion
            //backgroundWorker1.RunWorkerAsync();
            if (radioButton1.Checked)
                guanji();
            MessageBox.Show("切片完成！");
            this.DialogResult = DialogResult.OK;
        }

        private float GetLineSymbolLength(ISymbolDB symbolDataBase, string SymbolCode)
        {
            tagRECT r = new tagRECT();
            ILineSymbol l = symbolDataBase.GetLineSymbolByCode(Convert.ToInt32(SymbolCode));
            if (l == null)
                return 0;
            l.CalcSymbolRectByGU(ref r);
            return (r.right - r.left);
        }

        #region 初始化输出设置
        private bool InitOutputPath(string strOutputPath)
        {
            if (!Directory.Exists(strOutputPath))
            {
                if (DialogResult.Yes == MessageBox.Show("地图输出路径不存在，是否立即创建新目录！", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    Directory.CreateDirectory(strOutputPath);
                }
                else
                {
                    return false;
                }
            }
            else if (Directory.GetFiles(strOutputPath).Length > 0 || Directory.GetDirectories(strOutputPath).Length > 0)
            {
                if (DialogResult.Yes == MessageBox.Show("地图输出路径“" + strOutputPath + "”不为空，需要清空目录下所有文件夹及文件。\n确定清空目录吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    try
                    {
                        Directory.Delete(strOutputPath, true);
                        Directory.CreateDirectory(strOutputPath);
                    }
                    catch (Exception)
                    {
                        //MessageBox.Show(ex.Message);
                    }
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 输出路径是否包含中文字符
        /// </summary>
        /// <returns></returns>
        private bool IsOutputPathContainChinese()
        {
            string str = this.txtOutputPath.Text.Trim();
            for (int i = 0; i < str.Length; ++i)
            {
                Regex rx = new Regex("^[\u4e00-\u9fa5]$");
                if (rx.IsMatch(str[i].ToString()))
                {
                    return true;
                }
            }
            return false;
        }
        #endregion


        private void btnAddNewScale_Click(object sender, EventArgs e)
        {
            //判断文本框是否为空，并通过正则表达式判断文本框中是否包含字符
            string strScale = txtNewScale.Text.Trim();
            if (strScale == "")
            {
                MessageBox.Show("请输入比例尺!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtNewScale.Focus();
                return;
            }

            //判断输入的比例尺格式是否符合标准
            string strRegExpress = @"^[1-9]+[ ]*:[ ]*\d+$|^\d+$";
            if (!System.Text.RegularExpressions.Regex.IsMatch(strScale, strRegExpress))
            {
                MessageBox.Show("输入的比例尺格式有误，请以正确的格式输入!\n示例：1:250000\n         1 : 250000\n         250000", "提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtNewScale.Focus();
                return;
            }

            //根据输入的比例尺是否包含分号进行分别处理
            bool isRightScaleString = false;
            double mapDis = 0.0; double realDis = 0.0;
            if (strScale.Contains(":"))
            {
                string[] strScaleArray = strScale.Split(':');
                if (double.TryParse(strScaleArray[0], out mapDis) && double.TryParse(strScaleArray[1], out realDis))
                {
                    //如果图面距离的值大于1，则需要将他的值换算为1
                    if (mapDis > 1)
                    {
                        realDis = realDis / mapDis;
                        mapDis = 1;
                    }
                    isRightScaleString = true;
                }
            }
            else
            {
                if (double.TryParse(strScale, out realDis))
                {
                    mapDis = 1;
                    isRightScaleString = true;
                }
            }

            if (isRightScaleString)
            {
                string strLsScaleString = mapDis + " : " + realDis.ToString("#,#");
                if (!scaleList.ContainsKey(realDis))
                {
                    scaleList.Add(realDis, strLsScaleString);
                    scaleDic.Add(strLsScaleString, realDis);
                    this.AddScale2ListBox();
                }
            }
            txtNewScale.Text = "";
            txtNewScale.Focus();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if (outputPathBrowseDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string strOutputPath = outputPathBrowseDlg.SelectedPath;
                if (strOutputPath.EndsWith("\\"))
                {
                    strOutputPath = strOutputPath.Remove(strOutputPath.Length - 1, 1);
                }
                txtOutputPath.Text = strOutputPath;
            }
        }

        private void btnRemoveScale_Click(object sender, EventArgs e)
        {
            if (lsOutputScales.SelectedIndex != -1)
            {
                string strScaleText = lsOutputScales.SelectedItem.ToString().Trim();
                lsOutputScales.Items.RemoveAt(lsOutputScales.SelectedIndex);
                if (scaleDic.ContainsKey(strScaleText))
                {
                    scaleList.Remove(scaleDic[strScaleText]);
                    scaleDic.Remove(strScaleText);
                }
            }
        }

        private void btnSuggestion_Click(object sender, EventArgs e)
        {

        }

        private void AddScale2ListBox()
        {
            lsOutputScales.Items.Clear();
            foreach (double dblScale in scaleList.Keys)
            {
                string strScaleString = scaleList[dblScale];
                lsOutputScales.Items.Add(strScaleString);
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            //backgroundWorker1.CancelAsync();
        }

        private TileFeature EsirFeatureToTileFeature(IFeature pFeature, AccessOperation ao, Dictionary<string, string> GBCodeToSymbolCode)
        {
            string symbolCode = "";
            int index = pFeature.Table.FindField("GB");
            string GBCode = Convert.ToString(pFeature.get_Value(index));
            if (GBCodeToSymbolCode.Keys.Contains(GBCode))
            {
                symbolCode = GBCodeToSymbolCode[GBCode];
                if (symbolCode == "null")
                    return null;
            }
            else
            {
                string sqlStr = "Select SymbolCode from FeatureSymbol where FeatureCode=\"" + GBCode + "\"";
                DataTable dt = ao.ExecuteDataTable(sqlStr);
                if (dt.Rows.Count == 0)
                {
                    GBCodeToSymbolCode.Add(GBCode, "null");
                    return null;
                }
                symbolCode = Convert.ToString(dt.Rows[0][0]);
                if (symbolCode == "0" || symbolCode == "")
                    return null;
                GBCodeToSymbolCode.Add(GBCode, symbolCode);
            }


            string type = "";
            Geometry tileF = null;
            if (pFeature.Shape.GeometryType == esriGeometryType.esriGeometryPoint)
            {
                type = "Point";
                IPoint pPoint = pFeature.Shape as IPoint;
                CartoLab.GeometryLib.Geometries.Point tmpP = new CartoLab.GeometryLib.Geometries.Point(pPoint.X, pPoint.Y);
                tileF = tmpP;
            }
            else if (pFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline)
            {
                type = "Line";
                List<Coordinate> coors = ConvertPoints(pFeature.Shape as IPointCollection);
                LineString tmpLS = new LineString(coors.ToArray());
                tileF = tmpLS;
            }
            else
            {
                type = "Polygon";
                List<CartoLab.GeometryLib.Geometries.Polygon> polygons = new List<CartoLab.GeometryLib.Geometries.Polygon>();
                IPolygon4 polygon4 = pFeature.Shape as IPolygon4;
                if (polygon4.ExteriorRingBag == null)
                {
                    return null;
                }
                IGeometryBag exteriorRings = polygon4.ExteriorRingBag;

                IEnumGeometry exteriorRingsEnum = exteriorRings as IEnumGeometry;
                exteriorRingsEnum.Reset();
                IRing currentExteriorRing = exteriorRingsEnum.Next() as IRing;

                while (currentExteriorRing != null)
                {
                    IPointCollection pntss = currentExteriorRing as IPointCollection;
                    cartoGeometry.LinearRing shell = ConstructLinearRing(pntss);

                    IGeometryBag interiorRingsBag = polygon4.get_InteriorRingBag(currentExteriorRing);
                    IEnumGeometry interiorRingsEnum = interiorRingsBag as IEnumGeometry;
                    interiorRingsEnum.Reset();
                    IRing interiorRings = interiorRingsEnum.Next() as IRing;
                    List<cartoGeometry.LinearRing> holes = new List<cartoGeometry.LinearRing>();
                    while (interiorRings != null)
                    {
                        return null;
                        IPointCollection pntsin = interiorRings as IPointCollection;
                        holes.Add(ConstructLinearRing(pntsin));
                        interiorRings = interiorRingsEnum.Next() as IRing;
                    }

                    cartoGeometry.Polygon polygon;
                    if (holes.Count > 0)
                        polygon = new cartoGeometry.Polygon(shell, holes.ToArray());
                    else
                        polygon = new cartoGeometry.Polygon(shell);
                    polygons.Add(polygon);
                    currentExteriorRing = exteriorRingsEnum.Next() as IRing;
                }
                if (polygons.Count == 1)
                {
                    tileF = polygons[0];
                }
                else
                {
                    tileF = new cartoGeometry.MultiPolygon(polygons.ToArray());
                }
            }
            return new TileFeature(type, symbolCode, tileF);
        }

        private List<NewCoordinate> InsertPointInLine(List<NewCoordinate> line, NewCoordinate p)
        {
            for (int i = 0; i < line.Count - 1; i++)
            {
                LineSegment l = new LineSegment(line[i].c, line[i + 1].c);
                if (l.Distance(p.c) <= 0.0001 && PtIsInSegement(l.P0, l.P1, p.c))
                {
                    if (l.P0 == p.c)
                        line[i].type.AddRange(p.type);
                    else if (l.P1 == p.c)
                        line[i + 1].type.AddRange(p.type);
                    else
                        line.Insert(i + 1, p);
                    return line;
                }
            }
            line.Add(p);
            return line;
        }

        /// <summary>
        /// 对一条线进行去同斜率点的删除，如果a、b、c三点按顺序是同一条线，则将b点删掉
        /// </summary>
        /// <param name="coors">待处理线的点坐标</param>
        private void ClearSomeLinePoint(List<Coordinate> coors)
        {
            for (int i = 0; i < coors.Count - 2; i++)
            {
                if (PtIsInSegement(coors[i], coors[i + 2], coors[i + 1]))
                {
                    coors.RemoveAt(i + 1);
                    i--;
                }
            }
        }

        /// <summary>
        /// 获得直线等分点
        /// </summary>
        /// <param name="l">输入直线</param>
        /// <param name="Distance">等分距</param>
        /// <returns>等分点</returns>
        private Coordinate[] GetLineDivisionPoints(LineString l, double Distance)
        {
            int nextPtIndex = 1;
            double curDis = Distance;
            Coordinate curPt = l.Coordinates[0];
            List<Coordinate> DivisionPoints = new List<Coordinate>();
            bool isFisrt = false;
            DivisionPoints.Add(curPt);
            while (true)
            {
                double disNext = curPt.Distance(l.GetCoordinateN(nextPtIndex));
                if (disNext < curDis)
                {
                    curPt = l.GetCoordinateN(nextPtIndex);
                    nextPtIndex++;
                    curDis -= disNext;
                    isFisrt = true;
                    if (nextPtIndex == l.Coordinates.Length)
                    {
                        if (!DivisionPoints.Contains(l.Coordinates[nextPtIndex - 1]))
                        {
                            DivisionPoints.Add(l.Coordinates[nextPtIndex - 1]);
                        }
                        return DivisionPoints.ToArray();
                    }
                }
                else
                {
                    if (isFisrt)
                    {
                        curPt = GetPointByDistance(curPt, l.Coordinates[nextPtIndex], curDis);
                        DivisionPoints.Add(curPt);
                        curDis = Distance;
                        isFisrt = false;
                    }
                    else
                    {
                        int ratio = (int)(disNext / curDis);
                        for (int i = 1; i <= ratio; i++)
                        {
                            curPt = GetPointByDistance(curPt, l.Coordinates[nextPtIndex], curDis);
                            DivisionPoints.Add(curPt);
                            disNext -= curDis;
                        }
                    }
                }
            }

            //return DivisionPoints.ToArray();
        }

        private Coordinate GetPointByDistance(Coordinate p1, Coordinate p2, double distance)
        {
            LineSegment l = new LineSegment(p1, p2);
            return new Coordinate(Math.Round(p1.X + Math.Cos(l.Angle) * distance, 5), Math.Round(p1.Y + Math.Sin(l.Angle) * distance, 5));
        }

        /// <summary>
        /// 判断点是否在线段上
        /// </summary>
        /// <param name="p1">线段起点</param>
        /// <param name="p2">线段终点</param>
        /// <param name="c">需判断的点</param>
        /// <returns></returns>
        private bool PtIsInSegement(Coordinate p1, Coordinate p2, Coordinate c)
        {
            if (Math.Abs(p1.Distance(c) + p2.Distance(c) - p1.Distance(p2)) <= 0.0001)
                return true;
            return false;
        }

        struct GeometryAndPtIndex//用来记录包含了交点的对象及交点所在的索引号
        {

            public Geometry g;
            public List<int> indexs;
        }

        private List<GeometryAndPtIndex> ClipLineByPoints(Geometry g, Coordinate[] coordinates)
        {
            List<GeometryAndPtIndex> geos = new List<GeometryAndPtIndex>();
            int curPtIndex = 0;
            Coordinate curCo = g.Coordinates[curPtIndex];
            List<Coordinate> cos = new List<Coordinate>();

            for (int i = 0; i <= coordinates.Length; i++)
            {
                List<int> indexs = new List<int>();
                cos.Add(curCo);
                if (coordinates.Contains(curCo))
                    indexs.Add(cos.Count - 1);
                if (!cos.Contains(g.Coordinates[curPtIndex]))
                    cos.Add(g.Coordinates[curPtIndex]);
                for (int j = curPtIndex; j < g.Coordinates.Length; j++)
                {
                    if (i == coordinates.Length)
                    {
                        if (!cos.Contains(g.Coordinates[j]))
                            cos.Add(g.Coordinates[j]);
                    }
                    else
                    {
                        if (((g.Coordinates[curPtIndex].X - coordinates[i].X) * (g.Coordinates[curPtIndex + 1].X - coordinates[i].X)) > 0)
                        {
                            curPtIndex++;
                            if (!cos.Contains(g.Coordinates[curPtIndex]))
                                cos.Add(g.Coordinates[curPtIndex]);
                        }
                        else
                        {
                            cos.Add(coordinates[i]);
                            indexs.Add(cos.Count - 1);
                            curCo = coordinates[i];
                            curPtIndex++;
                            break;
                        }
                    }
                }
                LineString l = new LineString(cos.ToArray());
                GeometryAndPtIndex cap = new GeometryAndPtIndex();
                cap.g = l;
                cap.indexs = indexs;

                geos.Add(cap);
                cos.Clear();
            }

            return geos;
        }

        private float GetSymbolBuff(string SymbolCode, string type)
        {
            ISymbolDB symbolDataBase = new SymbolDBClass();
            float width = 0;
            symbolDataBase.LoadFromXML("miniSymbolDB.xml");
            if (type == "Point")
            {
                IPointSymbol p = symbolDataBase.GetPointSymbolByCode(Convert.ToInt32(SymbolCode));
                p.GetSymbolBuff(out width);
            }
            else if (type == "Line")
            {
                ILineSymbol l = symbolDataBase.GetLineSymbolByCode(Convert.ToInt32(SymbolCode));
                l.GetSymbolBuff(out width);
            }
            else
            {

            }

            return width;
        }

        private float GetSymbolWidth(ISymbolDB symbolDataBase, string symbolCode, string type)
        {
            float width = 0;
            if (type == "Point")
            {
                IPointSymbol p = symbolDataBase.GetPointSymbolByCode(Convert.ToInt32(symbolCode));
                if (p == null)
                    return 0;
                p.GetSymbolBuff(out width);
                width /= 2;
            }
            else if (type == "Line")
            {
                ILineSymbol l = symbolDataBase.GetLineSymbolByCode(Convert.ToInt32(symbolCode));
                if (l == null)
                    return 0;
                l.GetSymbolBuff(out width);
                width /= 2;
            }
            else
            {
                IAreaSymbol a = symbolDataBase.GetAreaSymbolByCode(Convert.ToInt32(symbolCode));
                if (a == null)
                    return 0;
                a.GetSymbolLineBuff(ref width);
                width /= 2;
            }

            return width;
        }

        public struct TileInfo
        {
            public double TileHeight;
            public double TileScale;//瓦片的比例尺
            public double MapScale;//制图比例尺
            public double resolution;
            public int TileRowCount;
            public int TileColumnCount;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="features"></param>
        /// <param name="path"></param>
        /// <param name="c">基点</param>
        private void SaveTileToXml(TileFeature[] features, string path, Coordinate c, TileInfo ti)
        {
            XmlDocument xmlD = new XmlDocument();
            XmlElement xmlOD = xmlD.CreateElement("scale_" + ti.TileScale.ToString() + "_" + ti.MapScale.ToString() + "_" + ti.resolution.ToString() + "_" + ti.TileRowCount.ToString() + "_" + ti.TileColumnCount.ToString());
            xmlD.AppendChild(xmlOD);
            foreach (TileFeature f in features)
            {
                SaveFeatureToXml(f, xmlD, xmlOD, c, ti.TileHeight * ti.resolution);
            }
            xmlD.Save(path);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="f"></param>
        /// <param name="xmlD"></param>
        /// <param name="xmlOD"></param>
        /// <param name="c">基点</param>
        private void SaveFeatureToXml(TileFeature f, XmlDocument xmlD, XmlElement xmlOD, Coordinate c, double TileHeight)
        {
            XmlElement xmlFeature = xmlD.CreateElement("Feature");
            xmlOD.AppendChild(xmlFeature);
            XmlElement xmlGeometry = xmlD.CreateElement("Geometry");
            xmlFeature.AppendChild(xmlGeometry);
            string geo = "";
            foreach (Coordinate coor in f.shape.Coordinates)
            {
                geo += "(" + Math.Round((coor - c).X, 3).ToString() + "," + Math.Round(TileHeight - (coor - c).Y, 3).ToString() + ");";
            }
            xmlGeometry.InnerText = geo;

            XmlElement xmlType = xmlD.CreateElement("Type");
            xmlFeature.AppendChild(xmlType);
            xmlType.InnerText = f.type;
            XmlElement xmlCode = xmlD.CreateElement("SymbolCode");
            xmlFeature.AppendChild(xmlCode);
            xmlCode.InnerText = f.SymbolCode;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            #region 切片
            double nowScale = mapControl.ActiveView.FocusMap.MapScale;
            IEnvelope fullExtent = new EnvelopeClass();
            fullExtent = mapControl.get_Layer(0).AreaOfInterest;
            for (int i = 1; i < mapControl.LayerCount; i++)
            {
                fullExtent.Union(mapControl.get_Layer(i).AreaOfInterest);
            }

            IPoint pStart = fullExtent.UpperLeft;
            double Width = fullExtent.Width;
            double Height = fullExtent.Height;

            ISymbolDB symbolDataBase = new SymbolDBClass();
            symbolDataBase.LoadFromXML("SymbolDB.xml");
            Dictionary<string, float> SymbolWidth = new Dictionary<string, float>();
            Dictionary<string, float> LineSymbolLength = new Dictionary<string, float>();
            //this.progressBar.Visible = true;
            int scalecount = 0;
            Dictionary<string, string> GBCodeToSymbolCode = new Dictionary<string, string>();
            foreach (var singlescale in scaleList)
            {
                scalecount++;
                this.progressBar.Value = 0;
                //this.progressText = "共有" + scaleList.Count + "个比例尺，当前在第" + scalecount.ToString()
                //    + "个";
                Directory.CreateDirectory(txtOutputPath.Text + "\\" + singlescale.Key.ToString());
                double scale = singlescale.Key;
                mapControl.ActiveView.FocusMap.MapScale = scale;
                IPoint p = new ESRI.ArcGIS.Geometry.PointClass();
                p.X = pStart.X + mapControl.ActiveView.Extent.Width / 2;
                p.Y = pStart.Y - mapControl.ActiveView.Extent.Height / 2;
                IEnvelope tmpE = mapControl.ActiveView.Extent;
                tmpE.CenterAt(p);
                mapControl.ActiveView.Extent = tmpE;
                mapControl.Refresh();

                ESRI.ArcGIS.esriSystem.tagRECT rect = new ESRI.ArcGIS.esriSystem.tagRECT();
                rect.bottom = 256;
                rect.left = 0;
                rect.right = 256;
                rect.top = 0;
                int StartPX = 0;
                int StartPY = 0;
                mapControl.ActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint(pStart, out StartPX, out StartPY);
                IEnvelope mapRect = new EnvelopeClass();
                mapControl.ActiveView.ScreenDisplay.DisplayTransformation.TransformRect(mapRect, ref rect, 1);
                double WorldTileWidth = mapRect.Height;
                int ScreenTileWidth = 256;
                #region 地图切片
                int nowCount = 0;
                int Hcount = (int)(Height / WorldTileWidth) + 1;
                int Wcount = (int)(Width / WorldTileWidth) + 1;
                AccessOperation ao = new AccessOperation(Application.StartupPath + "\\rules.mdb");
                for (int i = 0; i < Hcount; i++)
                {
                    for (int j = 0; j < Wcount; j++)
                    {
                        nowCount++;
                        int per = (int)((float)nowCount * 100 / (float)Hcount / (float)Wcount);
                        backgroundWorker1.ReportProgress(per);
                        #region 构建要素筛选范围
                        IPointCollection pc = new PolygonClass();
                        IPoint p1 = new PointClass();
                        IPoint p2 = new PointClass();
                        IPoint p3 = new PointClass();
                        IPoint p4 = new PointClass();
                        p1.X = pStart.X + j * WorldTileWidth;
                        p1.Y = pStart.Y - i * WorldTileWidth;
                        p2.X = pStart.X + (j + 1) * WorldTileWidth;
                        p2.Y = pStart.Y - i * WorldTileWidth;
                        p3.X = pStart.X + (j + 1) * WorldTileWidth;
                        p3.Y = pStart.Y - (i + 1) * WorldTileWidth;
                        p4.X = pStart.X + j * WorldTileWidth;
                        p4.Y = pStart.Y - (i + 1) * WorldTileWidth;

                        pc.AddPoint(p1);
                        pc.AddPoint(p2);
                        pc.AddPoint(p3);
                        pc.AddPoint(p4);
                        pc.AddPoint(p1);
                        IPolygon pPolygon = pc as IPolygon;
                        #endregion

                        #region 构建要素切片框

                        Coordinate[] coords = new Coordinate[5];
                        Coordinate leftUp = null;

                        Coordinate rightBottom = null;
                        leftUp = new Coordinate(StartPX + j * ScreenTileWidth, StartPY + i * ScreenTileWidth);
                        rightBottom = new Coordinate(StartPX + (j + 1) * ScreenTileWidth, StartPY + (i + 1) * ScreenTileWidth);
                        coords[0] = leftUp;
                        coords[1] = new Coordinate(rightBottom.X, leftUp.Y);
                        coords[2] = new Coordinate(rightBottom.X, rightBottom.Y);
                        coords[3] = new Coordinate(leftUp.X, rightBottom.Y);
                        coords[4] = leftUp;
                        LinearRing lr = new LinearRing(coords);
                        Geometry tileGeo = new CartoLab.GeometryLib.Geometries.Polygon(lr);
                        #endregion

                        ISpatialFilter pSpatialFilter = new SpatialFilterClass();
                        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                        pSpatialFilter.Geometry = pPolygon;
                        List<TileFeature> tileFeatures = new List<TileFeature>();
                        for (int k = 0; k < mapControl.LayerCount; k++)
                        {
                            IFeatureLayer pBackLayer = mapControl.get_Layer(k) as IFeatureLayer;
                            IFeatureSelection pFeatureSelection = pBackLayer as IFeatureSelection;
                            pFeatureSelection.Clear();

                            pFeatureSelection.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                            ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
                            int ddd = pFeatureSelection.SelectionSet.Count;
                            if (pFeatureSelection.SelectionSet.Count == 0)
                                continue;
                            IEnumIDs pEnumIDs = pSelectionSet.IDs;
                            int id = pEnumIDs.Next();
                            while (id != -1)
                            {
                                IFeature pFeature = pBackLayer.FeatureClass.GetFeature(id);

                                TileFeature f = EsirFeatureToTileFeature(pFeature, ao, GBCodeToSymbolCode);
                                if (f == null)
                                {
                                    id = pEnumIDs.Next();
                                    continue;
                                }
                                Geometry ExtGeo = null;
                                var ratio = singlescale.Key / 50000;
                                float width = 0;
                                if (SymbolWidth.Keys.Contains(f.SymbolCode))
                                    width = SymbolWidth[f.SymbolCode];
                                else
                                {
                                    width = GetSymbolWidth(symbolDataBase, f.SymbolCode, f.type);
                                    SymbolWidth.Add(f.SymbolCode, width);
                                }
                                ExtGeo = f.shape.Buffer(width);
                                bool isContains = tileGeo.Contains(ExtGeo);
                                bool isIntersects = tileGeo.Intersects(ExtGeo);
                                if (f.type == "Point")
                                {
                                    #region 点
                                    if (isContains || isIntersects)
                                        tileFeatures.Add(f);
                                    #endregion
                                }
                                else if (f.type == "Line")
                                {
                                    #region 线
                                    //若相交
                                    if (tileGeo.Intersects(f.shape))
                                    {
                                        //若完全包含
                                        if (tileGeo.Contains(f.shape))
                                        {
                                            tileFeatures.Add(f);
                                        }
                                        else//相交不包含，需要对线进行切割和延伸
                                        {
                                            LineString tmpLr = new LineString(coords);
                                            Geometry intersectGeo = tmpLr.Intersection(f.shape);
                                            //将对象根据符号单元长度分为N分
                                            float lineSymbolLine = 0;
                                            if (LineSymbolLength.ContainsKey(f.SymbolCode))
                                                lineSymbolLine = LineSymbolLength[f.SymbolCode];
                                            else
                                            {
                                                lineSymbolLine = GetLineSymbolLength(symbolDataBase, f.SymbolCode);
                                                LineSymbolLength.Add(f.SymbolCode, lineSymbolLine);
                                            }
                                            if (lineSymbolLine == 0)
                                            {
                                                id = pEnumIDs.Next();
                                                continue;
                                            }
                                            LineString l = (LineString)f.shape;
                                            //等分点
                                            Coordinate[] divisionPts = GetLineDivisionPoints(l, lineSymbolLine);
                                            //筛选过会的交点
                                            List<Coordinate> intsersectPts = new List<Coordinate>();
                                            for (int n = 0; n < intersectGeo.Coordinates.Length; n++)
                                            {
                                                if (!divisionPts.Contains(intersectGeo.Coordinates[n]))
                                                    intsersectPts.Add(intersectGeo.Coordinates[n]);
                                            }

                                            #region 将交点和等分点按线的顺序构造成一个新的坐标
                                            List<NewCoordinate> newLine = new List<NewCoordinate>();
                                            //先将原点坐标插入序列
                                            foreach (var c in f.shape.Coordinates)
                                            {
                                                NewCoordinate nc = new NewCoordinate();
                                                nc.c = c;
                                                nc.type = new List<int>();
                                                nc.type.Add(1);
                                                newLine.Add(nc);
                                            }
                                            //再依次将交点和符号化节点插入
                                            foreach (var item in intsersectPts)
                                            {
                                                NewCoordinate nc = new NewCoordinate();
                                                nc.c = item;
                                                nc.type = new List<int>();
                                                nc.type.Add(2);
                                                newLine = InsertPointInLine(newLine, nc);
                                            }
                                            foreach (var item in divisionPts)
                                            {
                                                NewCoordinate nc = new NewCoordinate();
                                                nc.c = item;
                                                nc.type = new List<int>();
                                                nc.type.Add(3);
                                                newLine = InsertPointInLine(newLine, nc);
                                            }
                                            #endregion

                                            //将根据交点和符号化节点将对象分为若干个对象

                                            List<List<NewCoordinate>> allNewF = new List<List<NewCoordinate>>();
                                            List<NewCoordinate> newF = new List<NewCoordinate>();
                                            #region 根据交点将对象分为若干个对象
                                            for (int kk = 0; kk < newLine.Count; kk++)
                                            {
                                                if (kk == newLine.Count - 1)
                                                {
                                                    newF.Add(newLine[kk]);
                                                    List<NewCoordinate> newF1 = new List<NewCoordinate>();
                                                    foreach (var item in newF)
                                                    {
                                                        newF1.Add(item);
                                                    }
                                                    allNewF.Add(newF1);
                                                    newF.Clear();
                                                    break;
                                                }

                                                if (newF.Count == 0)
                                                {
                                                    newF.Add(newLine[kk]);
                                                    continue;
                                                }
                                                else
                                                {
                                                    newF.Add(newLine[kk]);
                                                    if (newLine[kk].type.Contains(2))
                                                    {

                                                        List<NewCoordinate> newF1 = new List<NewCoordinate>();
                                                        foreach (var item in newF)
                                                        {
                                                            newF1.Add(item);
                                                        }
                                                        allNewF.Add(newF1);
                                                        newF.Clear();
                                                        kk--;
                                                        continue;
                                                    }


                                                }
                                            }
                                            #endregion
                                            #region 将在瓦片外的线删掉
                                            for (int m = 0; m < allNewF.Count; m++)
                                            {
                                                newF = allNewF[m];
                                                foreach (var c in newF)
                                                {
                                                    if (tileGeo.Touches(new CartoLab.GeometryLib.Geometries.Point(c.c)) || tileGeo.Contains(new CartoLab.GeometryLib.Geometries.Point(c.c)))
                                                    {
                                                        ;
                                                    }
                                                    else
                                                    {
                                                        allNewF.RemoveAt(m);
                                                        m--;
                                                        break;
                                                    }
                                                }
                                            }
                                            #endregion

                                            foreach (var item in allNewF)
                                            {

                                                List<Coordinate> coors = new List<Coordinate>();
                                                #region 将线的两段向符号化节点延伸
                                                NewCoordinate first = item[0];
                                                NewCoordinate last = item[item.Count - 1];

                                                int firstIndex = newLine.IndexOf(first);
                                                for (int m = firstIndex - 1; m >= 0; m--)
                                                {
                                                    coors.Insert(0, newLine[m].c);
                                                    if (newLine[m].type.Contains(3))
                                                        break;
                                                }
                                                foreach (var geo in item)
                                                {
                                                    coors.Add(geo.c);
                                                }

                                                int lastIndex = newLine.IndexOf(last);
                                                for (int m = lastIndex + 1; m < newLine.Count; m++)
                                                {
                                                    coors.Add(newLine[m].c);
                                                    if (newLine[m].type.Contains(3))
                                                        break;
                                                }
                                                #endregion

                                                ClearSomeLinePoint(coors);
                                                Geometry newG = new LineString(coors.ToArray());
                                                TileFeature newFeature = new TileFeature(f.type, f.SymbolCode, newG);
                                                tileFeatures.Add(newFeature);
                                            }

                                        }

                                    }

                                    #endregion
                                }
                                else
                                {
                                    #region 面
                                    if (isContains || isIntersects)
                                        tileFeatures.Add(f);
                                    #endregion
                                }
                                id = pEnumIDs.Next();
                            }


                        }
                        TileInfo ti = new TileInfo();
                        SaveTileToXml(tileFeatures.ToArray(), txtOutputPath.Text + "\\" + singlescale.Key.ToString() + "\\" + i.ToString() + "_" + j.ToString() + ".xml", tileGeo.Coordinates[3], ti);
                    }
                }
                #endregion
            }
            #endregion
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar.Value = (int)e.ProgressPercentage;
            this.progressText.Text = (e.ProgressPercentage).ToString() + "%";
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                this.DialogResult = DialogResult.Cancel;
            else
            {
                if (e.Error.Message == "")
                {
                    MessageBox.Show("切片完成!");
                    if (radioButton1.Checked)
                        guanji();
                    MessageBox.Show("切片完成！");
                    this.DialogResult = DialogResult.OK;
                }
                else
                    MessageBox.Show(e.Error.Message);
            }
        }

        private cartoGeometry.LinearRing ConstructLinearRing(IPointCollection pnts)
        {
            List<cartoGeometry.Coordinate> coors = ConvertPoints(pnts);
            if (coors == null)
                return null;
            if (!coors[0].Equals2D(coors[coors.Count - 1]))
                coors.Add(coors[0].Clone() as cartoGeometry.Coordinate);
            return new cartoGeometry.LinearRing(coors.ToArray());
        }


        private List<cartoGeometry.Coordinate> ConvertPoints(IPointCollection pnts)
        {
            if (pnts == null)
                return null;
            List<cartoGeometry.Coordinate> coors = new List<cartoGeometry.Coordinate>();
            IPoint pnt;
            for (int i = 0; i < pnts.PointCount; ++i)
            {
                pnt = pnts.get_Point(i);
                //edited by tanyongbin followed by fish
                coors.Add(new cartoGeometry.Coordinate(pnt.X, pnt.Y));
                //coors.Add(new cartoGeometry.Coordinate(pnt.X, pnt.Y));
                //coors.Add(new cartoGeometry.Coordinate(pnt.X, pnt.Y));
            }
            return coors;
        }

        public void guanji()
        {
            try
            {
                //启动本地程序并执行命令
                Process.Start("Shutdown.exe", " -s -t 0");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        //----------重启
        public void chongqi()
        {
            try
            {
                //启动本地程序并执行命令
                Process.Start("shutdown.exe", " -r -t 0");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory=Application.StartupPath;
            ofd.Filter = "符号库文件(*.xml)|*.xml|所有文件(*.*)|*.*";
            if(ofd.ShowDialog()==DialogResult.OK)
            {
                textBox1.Text = ofd.FileName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Application.StartupPath;
            ofd.Filter = "符号库文件(*.mdb)|*.mdb|所有文件(*.*)|*.*";
            if(ofd.ShowDialog()==DialogResult.OK)
            {
                textBox2.Text = ofd.FileName;
            }
        }
    }

}
